/*
 * version date author 
 * ────────────────────────────────── 
 * 1.0 2010-9-17 Neal Miao 
 */
package cn.miao.photoprinter.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Random;

import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;

/**
 * 图片处理工具类
 * 
 * @author Neal Miao
 * @version
 * @since v 1.0
 * @Date 2011 May 24, 2011 7:24:50 PM
 * 
 * @see
 */
public class ImageHelper {
	
	/**
	 * 从Uri获取Bitmap
	 *
	 * @param context
	 * @param uri
	 */
	public static Bitmap getBitmapFromUri(Context context, Uri uri) {
		try {
			// 读取uri所在的图片
			Bitmap bitmap = MediaStore.Images.Media.getBitmap(
					context.getContentResolver(), uri);
			return bitmap;
		} catch (Exception e) {
			Log.e("[Android]", e.getMessage());
			Log.e("[Android]", "目录为：" + uri);
			e.printStackTrace();
			return null;
		}
	}


	/**
	 * 从SD卡里面读取图片
	 * 
	 * @param fileName
	 * @return Bitmap
	 * @since v 1.0
	 */
	public static Bitmap getBitmapByPath(String filePath) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 6;
		Bitmap bm = BitmapFactory.decodeFile(filePath, options);
		return bm;
	}

	/**
	 * 保存图片到SD卡， 指定路径， 绝对路径
	 *
	 * @param picName
	 * @param picPath
	 * @param mBitmap
	 */
	public static void saveBitmap2Path(String picName, String picPath, Bitmap mBitmap) {
		File tmp = new File(picPath);
		if (!tmp.exists()) {
			tmp.mkdirs();
		}
		File f = new File(picPath + picName + ".png");
		FileOutputStream fOut = null;
		try {
			f.createNewFile();
			fOut = new FileOutputStream(f);
			mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
			fOut.flush();
			fOut.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * 将图片文件Base64转字节流
	 *
	 * @param filePath
	 * @param imageName
	 * @return
	 */
	public static String image2ByteString(String filePath, String imageName) {
		File tmp = new File(filePath);
		if (!tmp.exists()) {
			return "";
		}
		int bufferSize = 1024;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			File f = new File(filePath, imageName);
			FileInputStream fis = new FileInputStream(f);
			BufferedInputStream bis = new BufferedInputStream(fis);
			int ch;
			int i = 0;
			while ((ch = bis.read()) != -1) {
				baos.write(ch);
				if (i++ == bufferSize) {
					baos.flush();
					i = 0;
				}
			}
			baos.flush(); // 提交文件流，很关键
			bis.close();
			return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT).toString();
		} catch (FileNotFoundException e) {
			return "";
		} catch (IOException e) {
			return "";
		}
	}

	/**
	 * 上传文件
	 * 
	 * @param fileServer
	 * @param filePath
	 * @param params
	 * @return String
	 * @since v 1.0
	 */
	public static void uploadFile(String fileServer, String filePath,
			Map<String, String> params) {
		HttpURLConnection conn = null;
		DataOutputStream dos = null;
		// String existingFileName = "D:\\o1.jpg";
		String lineEnd = "\r\n";
		String twoHyphens = "--";
		String boundary = generateBoundary();
		int bytesRead, bytesAvailable, bufferSize;
		byte[] buffer;
		int maxBufferSize = 1 * 1024 * 1024;
		String responseFromServer = "";
		try {
			FileInputStream fileInputStream = new FileInputStream(new File(
					filePath));
			URL url = new URL(fileServer);
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);
			dos = new DataOutputStream(conn.getOutputStream());
			// 表单字段
			StringBuffer sb = new StringBuffer();
			for (String key : params.keySet()) {
				sb = sb.append("--");
				sb = sb.append(boundary);
				sb = sb.append("\r\n");
				sb = sb.append("Content-Disposition: form-data; name=\"" + key
						+ "\"\r\n\r\n");
				sb = sb.append(URLEncoder.encode(params.get(key), "utf-8"));
				sb = sb.append("\r\n");
			}
			dos.writeBytes(sb.toString());
			// end表单字段
			// 文件
			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
					+ filePath + "\"" + lineEnd);
			dos.writeBytes(lineEnd);
			// create a buffer of maximum size
			bytesAvailable = fileInputStream.available();
			bufferSize = Math.min(bytesAvailable, maxBufferSize);
			buffer = new byte[bufferSize];
			// read file and write it into form...
			bytesRead = fileInputStream.read(buffer, 0, bufferSize);
			while (bytesRead > 0) {
				dos.write(buffer, 0, bufferSize);
				bytesAvailable = fileInputStream.available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = fileInputStream.read(buffer, 0, bufferSize);
			}
			// send multipart form data necesssary after file data...
			dos.writeBytes(lineEnd);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

			// close streams
			System.out.println("File is written");
			fileInputStream.close();
			dos.flush();
			dos.close();
		} catch (MalformedURLException ex) {
			System.out.println("error: " + ex.getMessage());
		} catch (IOException ioe) {
			System.out.println("error: " + ioe.getMessage());
		}
		// ------------------ read the SERVER RESPONSE
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));
			while (br.read() != -1) {
				responseFromServer += br.readLine();
			}
			br.close();
			System.out.println(responseFromServer);
		} catch (IOException ioex) {
		}
	}

	protected static String generateBoundary() {
		char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
				.toCharArray();
		StringBuilder buffer = new StringBuilder();
		Random rand = new Random();
		int count = rand.nextInt(11) + 30; // a random size from 30 to 40
		for (int i = 0; i < count; i++) {
			buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
		}
		return buffer.toString();
	}

	/**
	 * 获取文件名字
	 * 
	 * @param fileName
	 * @return String
	 * @since v 1.0
	 */
	public static String getFileName(String fileName) {
		if (fileName.indexOf('\\') > -1) {
			fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
		}
		if (fileName.indexOf('/') > -1) {
			fileName = fileName.substring(fileName.lastIndexOf('/') + 1);
		}
		return fileName;
	}

	/**
	 * Apache上传
	 * 
	 * @return void
	 * @since v 1.0
	 */
	public static String apacheUploadFile(String fileServer, String filePath,
			Map<String, String> params) {
		HttpPost request = new HttpPost(fileServer);

		// FileBody bin = new FileBody(new File(filePath),
		// getFileName(filePath),
		// "image/jpeg", HTTP.UTF_8);
		FileBody bin = new FileBody(new File(filePath), getFileName(filePath),
				"application/octet-stream", HTTP.UTF_8);
		MultipartEntity entity = new MultipartEntity(
				HttpMultipartMode.BROWSER_COMPATIBLE, null,
				Charset.forName(HTTP.UTF_8));
		entity.addPart("images", bin);
		for (String key : params.keySet()) {
			try {
				entity.addPart(
						key,
						new StringBody(URLEncoder.encode(params.get(key),
								"utf-8")));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		request.setEntity(entity);
		HttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		try {
			response = client.execute(request);
		} catch (ClientProtocolException e) {
			Log.e("Apache Upload", e.getMessage());
		} catch (IOException e) {
			Log.e("Apache Upload", e.getMessage());
		}
		if (response == null) {
			return "";
		}
		String result = null;
		if (response.getStatusLine().getStatusCode() == 200) {
			try {
				result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
			} catch (ParseException e) {
				result = e.getMessage();
			} catch (IOException e) {
				result = e.getMessage();
			}
		} else {
			result = "error response" + response.getStatusLine().toString();
		}
		Log.i("info", result); // 不乱码
		return result;
	}

	public static Bitmap compress(File f, float ratio) {
		try {
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(new FileInputStream(f), null, o);

			// The new size we want to scale to
			final int REQUIRED_WIDTH = (int) (o.outWidth * ratio);
			final int REQUIRED_HIGHT = (int) (o.outHeight * ratio);
			// Find the correct scale value. It should be the power of 2.
			int scale = 1;
			while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
					&& o.outHeight / scale / 2 >= REQUIRED_HIGHT)
				scale *= 2;

			// Decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		} catch (FileNotFoundException e) {
		}
		return null;
	}
}
